package com.gzhryc.shared_device.oem.h5.agent.controllers.api.v1;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.commons.lang3.time.DateUtils;

import com.gzhryc.common.DateTools;
import com.gzhryc.common.NumberTools;
import com.gzhryc.common.StringTools;
import com.gzhryc.common.api.DefaultAPIResponse;
import com.gzhryc.common.config.DefaultEnum;
import com.gzhryc.common.config.PropertyTools;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.json.JsonTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.pay.enums.ReceivingMoneyType;
import com.gzhryc.servlet.WebUtils;
import com.gzhryc.servlet.annotation.Route;
import com.gzhryc.shared_device.base.enums.EOperatorType;
import com.gzhryc.shared_device.base.enums.EPayType;
import com.gzhryc.shared_device.base.enums.WalletOperateEnum;
import com.gzhryc.shared_device.base.models.OperateInfo;
import com.gzhryc.shared_device.common.payment.dao.db.PayAccountGroup;
import com.gzhryc.shared_device.common.payment.dao.db.WXTransferMoneyOrder;
import com.gzhryc.shared_device.common.payment.dao.enums.WXPayConfigEnum;
import com.gzhryc.shared_device.common.payment.dao.models.CashWithdrawalConfig;
import com.gzhryc.shared_device.common.payment.services.PayAccountGroupService;
import com.gzhryc.shared_device.oem.code.agent.dao.db.AgentRelationWallet;
import com.gzhryc.shared_device.oem.code.agent.services.AgentRelationWalletService;
import com.gzhryc.shared_device.oem.code.profit.dao.enums.BusinessOrderUserProfitEnum;
import com.gzhryc.shared_device.oem.code.profit.service.BusinessOrderUserProfitService;
import com.gzhryc.shared_device.oem.code.user.dao.db.User;
import com.gzhryc.shared_device.oem.code.user.dao.db.UserTransferMoneyOrder;
import com.gzhryc.shared_device.oem.code.user.dao.db.UserTransferMoneyQrcode;
import com.gzhryc.shared_device.oem.code.user.dao.db.UserTransferMoneyWX;
import com.gzhryc.shared_device.oem.code.user.dao.db.UserWallet;
import com.gzhryc.shared_device.oem.code.user.dao.db.UserWalletOperate;
import com.gzhryc.shared_device.oem.code.user.dao.enums.UserTransferMoneyOrderEnum;
import com.gzhryc.shared_device.oem.code.user.dao.enums.UserTransferMoneyQrcodeEnum;
import com.gzhryc.shared_device.oem.code.user.services.UserService;
import com.gzhryc.shared_device.oem.code.user.services.UserTransferMoneyOrderService;
import com.gzhryc.shared_device.oem.code.user.services.UserTransferMoneyQrcodeService;
import com.gzhryc.shared_device.oem.code.user.services.UserTransferMoneyWXService;
import com.gzhryc.shared_device.oem.code.user.services.UserWalletOperateService;
import com.gzhryc.shared_device.oem.code.user.services.UserWalletService;
import com.gzhryc.shared_device.oem.code.user.services.dto.UserWalletOperateSearch;
import com.gzhryc.shared_device.oem.h5.agent.ClientAPICodeConstants;
import com.gzhryc.shared_device.oem.h5.agent.ELoginUserRoleType;
import com.gzhryc.shared_device.oem.h5.agent.LoginUser;
import com.gzhryc.shared_device.oem.h5.agent.LoginUserSessionManager;
import com.gzhryc.shared_device.oem.h5.agent.WebConstants;
import com.gzhryc.shared_device.oem.h5.agent.dto.VerifyCodeData;
import com.gzhryc.shared_device.oem.h5.agent.dto.api.v1.my.MyWalletInfoResponse;
import com.gzhryc.shared_device.oem.h5.agent.dto.api.v1.my.MyWalletOperateListRequest;
import com.gzhryc.shared_device.oem.h5.agent.dto.api.v1.my.MyWalletOperateListResponse;
import com.gzhryc.shared_device.oem.h5.agent.dto.api.v1.my.MyWalletTransferMoneyApplyRequest;
import com.gzhryc.shared_device.oem.h5.agent.dto.api.v1.my.MyWalletTransferMoneyApplyResponse;
import com.gzhryc.shared_device.oem.h5.agent.dto.api.v1.my.TransferMoneyQrcodeBindRequest;
import com.gzhryc.shared_device.oem.h5.agent.dto.api.v1.my.TransferMoneyQrcodeInfoResponse;
import com.gzhryc.shared_device.oem.h5.agent.dto.api.v1.my.TransferMoneyWXUserBindRequest;
import com.gzhryc.shared_device.oem.h5.agent.dto.api.v1.my.TransferMoneyWXUserListRequest;
import com.gzhryc.shared_device.oem.h5.agent.dto.api.v1.my.TransferMoneyWXUserListResponse;
import com.gzhryc.shared_device.oem.h5.agent.dto.api.v1.my.TransferWalletInfoRequest;
import com.gzhryc.shared_device.oem.h5.agent.dto.api.v1.my.TransferWalletInfoResponse;
import com.gzhryc.weixin.gzh.WxAuthorityApi;
import com.gzhryc.weixin.gzh.WxUserApi;
import com.gzhryc.weixin.gzh.msg.Oauth2AccessToken;
import com.gzhryc.weixin.gzh.msg.Oauth2WeixinUser;

/**
 * 我的钱包相关接口
 * @version 2023-05-17
 */
public class MyWalletController {

    static Logger log = Logger.getLogger(MyWalletController.class);

    @Route(value = "/agent/api/v1/my/wallet/info.data")
    public MyWalletInfoResponse info(HttpServletRequest request) {
        MyWalletInfoResponse apiResp = new MyWalletInfoResponse(ClientAPICodeConstants.NULL_DATA);
        LoginUser loginUser = WebUtils.getAttribute(request, WebConstants.ATTR_LOGIN_USER,LoginUser.class);
        if(loginUser != null){
            apiResp.setCode(ClientAPICodeConstants.SUCCESS);

            Long money = 0L;
            Long relationWalletMoney = null;			//当前账号金额
            Long relationWalletWithdrawnMoney = null;		//当前账号已转出金额
            List<AgentRelationWallet> relationWalletList = null;
           
            //获取当前登陆账号类型
            if(ELoginUserRoleType.Partner.index().equals(loginUser.getRoleType()) 
            		|| ELoginUserRoleType.Dealer.index().equals(loginUser.getRoleType())) {
            	relationWalletList = AgentRelationWalletService.self().findByRelationUserId(loginUser.getId());
            	
            	relationWalletMoney = 0L;
            	relationWalletWithdrawnMoney = 0L;
            	
            	if(relationWalletList != null && relationWalletList.size() > 0) {
                	for(AgentRelationWallet relationWallet : relationWalletList) {
                		money = money + relationWallet.getMoney();
                		
                		if(relationWallet.getUserId().equals(loginUser.getParentId())) {
                			relationWalletMoney = relationWalletMoney + relationWallet.getMoney();
                			relationWalletWithdrawnMoney = relationWalletWithdrawnMoney + relationWallet.getWithdrawnMoney();
                		}
                	}
                }
            }
            
            List<UserWallet> walletList = UserWalletService.self().findJoinByUserId(loginUser.getId());
            if(walletList != null && walletList.size() > 0){
                apiResp.getBody().setItems(new ArrayList<>());

                for(UserWallet wallet : walletList){
                    money = money + wallet.getMoney() + wallet.getWithdrawalMoney() + wallet.getFreezeMoney();
                    
                    Long groupMoney = wallet.getMoney();
                    if(relationWalletList != null && relationWalletList.size() > 0) {
                    	for(AgentRelationWallet relationWallet : relationWalletList) {
                    		if(relationWallet.getAccountGroupId().equals(wallet.getAccountGroupId())) {
                    			groupMoney = groupMoney + relationWallet.getMoney();
                    		}
                    	}
                    }

                    MyWalletInfoResponse.Item item = new MyWalletInfoResponse.Item();
                    item.setAccountGroupId(wallet.getAccountGroupId());
                    item.setAccountGroupName(wallet.getAccountGroup().getName());
                    item.setMoney(NumberTools.getMoneyLiStr(groupMoney));
                    item.setWithdrawalMoney(wallet.getWithdrawalMoneyStr());
                    item.setFreezeMoney(wallet.getFreezeMoneyStr());

                    item.setWxBindType(0);      //0:代表不开放微信转账提现
                    if(wallet.getAccountGroup().getWxTransfer()){
                        if(WXPayConfigEnum.AppType.wxxcx.index().equals(wallet.getAccountGroup().getWxTransferAppType())){
                            item.setWxBindType(2);      //2:小程序
                            item.setAppletsId(wallet.getAccountGroup().getWxTransferAppId());
                            item.setAppletsJumpType(wallet.getAccountGroup().getAppletsJumpType());
                            item.setAppletsPath(wallet.getAccountGroup().getAppletsPath());
                        }else{
                            item.setWxBindType(1);      //1:公众号
                        }
                    }
                    apiResp.getBody().getItems().add(item);
                }
            }

            //总提现金额
            Integer totalWithdrawalMoney = UserTransferMoneyOrderService.self().sumTransferMoneyByUserIdAndState(loginUser.getId(), UserTransferMoneyOrderEnum.State.Success.index());
            //今年总收益
            Long yearIncomeMoney = BusinessOrderUserProfitService.self(new Date()).sumMoneyByUserIdAndState(loginUser.getId(), BusinessOrderUserProfitEnum.State.Finish.index());

            apiResp.getBody().setMoney(NumberTools.getMoneyLiStr(money));
            apiResp.getBody().setTotalWithdrawalMoney(NumberTools.getMoneyStr(totalWithdrawalMoney));
            apiResp.getBody().setYearIncomeMoney(NumberTools.getMoneyLiStr(yearIncomeMoney));
            
            if(relationWalletMoney != null && relationWalletWithdrawnMoney != null) {
            	apiResp.getBody().setRelationWalletMoney(NumberTools.getMoneyLiStr(relationWalletMoney));
            	apiResp.getBody().setRelationWalletWithdrawnMoney(NumberTools.getMoneyLiStr(relationWalletWithdrawnMoney));
            }
        }
        return apiResp;
    }

    @Route(value = "/agent/api/v1/transfer_money/wallet/info.data")
    public TransferWalletInfoResponse walletInfo(HttpServletRequest request) {
        TransferWalletInfoResponse apiResp = new TransferWalletInfoResponse(ClientAPICodeConstants.NULL_DATA);
        TransferWalletInfoRequest apiReq = WebUtils.getJsonRequest(request, TransferWalletInfoRequest.class);
        LoginUser loginUser = WebUtils.getAttribute(request, WebConstants.ATTR_LOGIN_USER,LoginUser.class);

        if(apiReq != null && apiReq.getBody().getAccountGroupId() != null && loginUser != null){
            UserWallet wallet = UserWalletService.self().getJoinByKeys(loginUser.getId(),apiReq.getBody().getAccountGroupId());
            if(wallet != null) {
                apiResp.setCode(ClientAPICodeConstants.SUCCESS);
                apiResp.getBody().setAccountGroupId(wallet.getAccountGroupId());
                apiResp.getBody().setAccountGroupName(wallet.getAccountGroup().getName());
                apiResp.getBody().setMoney(NumberTools.getMoneyStr(NumberTools.changeMoneyLi(wallet.getMoney())));
                apiResp.getBody().setWithdrawalMoney(NumberTools.getMoneyStr(NumberTools.changeMoneyLi(wallet.getWithdrawalMoney())));
                apiResp.getBody().setFreezeMoney(wallet.getFreezeMoneyStr());

                apiResp.getBody().setWxBindType(0);      //0:代表不开放微信转账提现
                if(wallet.getAccountGroup().getWxTransfer()){
                    if(WXPayConfigEnum.AppType.wxxcx.index().equals(wallet.getAccountGroup().getWxTransferAppType())){
                        apiResp.getBody().setWxBindType(2);      //2:小程序
                        apiResp.getBody().setAppletsId(wallet.getAccountGroup().getWxTransferAppId());
                        apiResp.getBody().setAppletsJumpType(wallet.getAccountGroup().getAppletsJumpType());
                        apiResp.getBody().setAppletsPath(wallet.getAccountGroup().getAppletsPath());
                    }else{
                        apiResp.getBody().setWxBindType(1);      //1:公众号
                    }
                }

                CashWithdrawalConfig cashWithdrawalConfig = new CashWithdrawalConfig();
                PayAccountGroup accountGroup = wallet.getAccountGroup();
                if(StringTools.isNotBlank(accountGroup.getTransferConfig())){
                    cashWithdrawalConfig = JsonTools.fromJson(accountGroup.getTransferConfig(),CashWithdrawalConfig.class);
                }

                apiResp.getBody().setMinMoney(cashWithdrawalConfig.getMinMoneyStr());
                apiResp.getBody().setMaxMoney(cashWithdrawalConfig.getMaxMoneyStr());
                apiResp.getBody().setDayUserMaxMoney(cashWithdrawalConfig.getDayUserMaxMoneyStr());
                apiResp.getBody().setCashWithdrawalWeeks(cashWithdrawalConfig.getCashWithdrawalWeeks());
                apiResp.getBody().setMonthStartDay(cashWithdrawalConfig.getMonthStartDay());
                apiResp.getBody().setMonthEndDay(cashWithdrawalConfig.getMonthEndDay());
                apiResp.getBody().setCashWithdrawalTimes(cashWithdrawalConfig.getCashWithdrawalTimes());
                apiResp.getBody().setServiceCharge(cashWithdrawalConfig.getServiceCharge());
            }
        }
        return apiResp;
    }

    @Route(value = "/agent/api/v1/my/wallet/operate/list.data")
    public MyWalletOperateListResponse profitDetailList(HttpServletRequest request) {
        MyWalletOperateListResponse apiResp = new MyWalletOperateListResponse(ClientAPICodeConstants.NULL_DATA, "暂无数据");
        MyWalletOperateListRequest apiReq = WebUtils.getJsonRequest(request, MyWalletOperateListRequest.class);
        if (apiReq != null && apiReq.getBody().getDay() != null) {
            LoginUser loginUser = WebUtils.getAttribute(request, WebConstants.ATTR_LOGIN_USER, LoginUser.class);
            if (loginUser != null) {
                Integer pageNo = apiReq.getBody().getPageNo() == null?1:apiReq.getBody().getPageNo();
                Date day = null;
                try {
                    day = DateUtils.parseDate(apiReq.getBody().getDay(),"yyyy-MM-dd");
                } catch (ParseException e) {
                    log.error(e.getMessage(),e);
                }

                if(day != null) {
                    Date startDate = DateTools.getDayStart(day);
                    Date endDate = DateTools.getDayEnd(day);

                    UserWalletOperateSearch search = new UserWalletOperateSearch();
                    search.setUserId(loginUser.getId());
                    search.setMoneyType(WalletOperateEnum.MoneyType.Money.index());
                    search.setType(apiReq.getBody().getType());
                    search.setStartDate(startDate);
                    search.setEndDate(endDate);

                    List<UserWalletOperate> userWalletOperateList = UserWalletOperateService.self(startDate).findBySearch(search, pageNo, WebConstants.PAGE_LIMIT);
                    if (userWalletOperateList != null && userWalletOperateList.size() > 0) {
                        apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                        apiResp.getBody().setItems(new ArrayList<>());

                        for (UserWalletOperate userWalletOperate : userWalletOperateList) {
                            MyWalletOperateListResponse.Item item = new MyWalletOperateListResponse.Item();
                            item.setTimeStr(DateFormatUtils.format(userWalletOperate.getCreateDate(), "hh:mm"));
                            item.setMoney(userWalletOperate.getMoneyStr());
                            item.setType(userWalletOperate.getType());
                            item.setNote(userWalletOperate.getOperateNote());
                            apiResp.getBody().getItems().add(item);
                        }
                    }
                }
            }
        }
        return apiResp;
    }
    
    @Route(value = { "/agent/api/v1/transfer_money/wx_user/bind.do" })
    public DefaultAPIResponse bindWXUser(HttpServletRequest request) {
        DefaultAPIResponse apiResp = new DefaultAPIResponse(ClientAPICodeConstants.EXECUTE_ERROR, "绑定失败，请稍后再试！");
        TransferMoneyWXUserBindRequest apiReq = WebUtils.getJsonRequest(request, TransferMoneyWXUserBindRequest.class);
        log.info("提现微信绑定，请求：{{0:json}}",apiReq);
        if (apiReq != null && StringTools.isNotBlank(apiReq.getBody().getAppId()) && StringTools.isNotBlank(apiReq.getBody().getName())
                && StringTools.isNotBlank(apiReq.getBody().getWxCode()) && StringTools.isNotBlank(apiReq.getBody().getPhoneValid())
                && StringTools.isNotBlank(apiReq.getBody().getPt())) {
            LoginUser loginUser = WebUtils.getAttribute(request, WebConstants.ATTR_LOGIN_USER, LoginUser.class);
            try {
                User user = UserService.self().getById(loginUser.getId());
                String key = user.getPhone() + "_" + apiReq.getBody().getPt();
                VerifyCodeData verifyCodeData = LoginUserSessionManager.self().getVerifyCode(key);
                if (verifyCodeData == null) {
                    apiResp.setMsg("请填写正确的手机验证码");
                    return apiResp;
                }

                if (DateTools.differenceMinute(verifyCodeData.getCreateDate(), new Date()) > 10) {
                    apiResp.setMsg("手机验证码超时");
                    return apiResp;
                }

                if (apiReq.getBody().getPhoneValid().equals(verifyCodeData.getCode())) {
                    Oauth2WeixinUser oauth2WxUser = null;
                    WxAuthorityApi wxAuthorityApi = LoginUserSessionManager.self().getWXAuthorityAPI(apiReq.getBody().getAppId());
                    if(wxAuthorityApi != null) {
                        Oauth2AccessToken oauth2AccessToken = wxAuthorityApi.getOauth2AccessToken(apiReq.getBody().getWxCode());
                        if (oauth2AccessToken != null) {
                            WxUserApi wxUserApi = LoginUserSessionManager.self().getWXUserAPI(apiReq.getBody().getAppId());
                            oauth2WxUser = wxUserApi.getWeixinUser(oauth2AccessToken);

                            UserTransferMoneyWX wxUser = UserTransferMoneyWXService.self().getByKeys(apiReq.getBody().getAppId(), oauth2WxUser.getOpenid(), loginUser.getId());
                            if (wxUser != null) {
                                throw new LogicException("该微信已注册");
                            }

                            UserTransferMoneyWX transferMoneyWX = new UserTransferMoneyWX();
                            transferMoneyWX.setAppId(apiReq.getBody().getAppId());
                            transferMoneyWX.setOpenId(oauth2WxUser.getOpenid());
                            transferMoneyWX.setUserId(loginUser.getId());
                            transferMoneyWX.setAppType(WXPayConfigEnum.AppType.wxgzh.index());
                            transferMoneyWX.setNickname(oauth2WxUser.getNickname());
                            transferMoneyWX.setFaceImg(oauth2WxUser.getHeadimgurl());
                            if(oauth2WxUser.getSex() == 1) {
                                transferMoneyWX.setSex(DefaultEnum.Sex.Female.index());
                            }else{
                                transferMoneyWX.setSex(DefaultEnum.Sex.Male.index());
                            }
                            transferMoneyWX.setName(apiReq.getBody().getName());
                            transferMoneyWX.setPhone(user.getPhone());

                            if (UserTransferMoneyWXService.self().add(transferMoneyWX)) {
                                apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                                LoginUserSessionManager.self().removeVerifyCode(key);
                            }
                        }else{
                            log.error("获取微信Oauth2AccessToken失败，wxCode = {{0}}",apiReq.getBody().getWxCode());
                        }
                    }else{
                        log.error("获取微信服务失败，APPID = {{0}}",apiReq.getBody().getAppId());
                    }
                } else {
                    apiResp.setMsg("手机验证码不正确");
                    return apiResp;
                }
            } catch (LogicException e) {
                apiResp.setMsg(e.getMessage());
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
        return apiResp;
    }

    @Route(value = { "/agent/api/v1/transfer_money/qrcode/bind.do" })
    public DefaultAPIResponse bindQrcode(HttpServletRequest request) {
        DefaultAPIResponse apiResp = new DefaultAPIResponse(ClientAPICodeConstants.EXECUTE_ERROR, "绑定失败，请稍后再试！");
        TransferMoneyQrcodeBindRequest apiReq = WebUtils.getJsonRequest(request, TransferMoneyQrcodeBindRequest.class);
        if (apiReq != null && StringTools.isNotBlank(apiReq.getBody().getPhoneValid()) && StringTools.isNotBlank(apiReq.getBody().getPt())
            && StringTools.isNotBlank(apiReq.getBody().getImgPath())) {
            LoginUser loginUser = WebUtils.getAttribute(request, WebConstants.ATTR_LOGIN_USER, LoginUser.class);

            User user = UserService.self().getById(loginUser.getId());
            String key = user.getPhone() + "_" + apiReq.getBody().getPt();
            VerifyCodeData verifyCodeData = LoginUserSessionManager.self().getVerifyCode(key);
            if(verifyCodeData == null){
                apiResp.setMsg("请填写正确的手机验证码");
                return apiResp;
            }

            if(DateTools.differenceMinute(verifyCodeData.getCreateDate(),new Date()) > 10){
                apiResp.setMsg("手机验证码超时");
                return apiResp;
            }

            if(apiReq.getBody().getPhoneValid().equals(verifyCodeData.getCode())){
                UserTransferMoneyQrcode transferMoneyQrcode = new UserTransferMoneyQrcode();
                transferMoneyQrcode.setUserId(user.getId());
                transferMoneyQrcode.setType(apiReq.getBody().getType());
                transferMoneyQrcode.setQrcode(apiReq.getBody().getImgPath());
                transferMoneyQrcode.setNote(apiReq.getBody().getNote());

                if(UserTransferMoneyQrcodeService.self().save(transferMoneyQrcode)){
                    apiResp.setCode(ClientAPICodeConstants.SUCCESS,null);
                    LoginUserSessionManager.self().removeVerifyCode(key);
                }
            }else{
                apiResp.setMsg("手机验证码不正确");
                return apiResp;
            }
        }
        return apiResp;
    }

    @Route(value = { "/agent/api/v1/transfer_money/wx_user/list.data" })
    public TransferMoneyWXUserListResponse findWXUserList(HttpServletRequest request) {
        TransferMoneyWXUserListResponse apiResp = new TransferMoneyWXUserListResponse(ClientAPICodeConstants.NULL_DATA, "暂无数据");
        LoginUser loginUser = WebUtils.getAttribute(request, WebConstants.ATTR_LOGIN_USER, LoginUser.class);
        TransferMoneyWXUserListRequest apiReq = WebUtils.getJsonRequest(request, TransferMoneyWXUserListRequest.class);
        if (apiReq != null) {
            if (apiReq.getBody().getAccountGroupId() != null) {
                try {
                    List<UserTransferMoneyWX> wxUserList = UserTransferMoneyWXService.self().findByUserIdAndAccountGroupId(loginUser.getId()
                            , apiReq.getBody().getAccountGroupId());
                    if (wxUserList != null && wxUserList.size() > 0) {
                        apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                        apiResp.getBody().setItems(new ArrayList<>());
                        for (UserTransferMoneyWX wxUser : wxUserList) {
                            TransferMoneyWXUserListResponse.Item item = new TransferMoneyWXUserListResponse.Item();
                            item.setAppId(wxUser.getAppId());
                            item.setOpenId(wxUser.getOpenId());
                            item.setFaceImg(wxUser.getFaceImg());
                            item.setNickname(wxUser.getNickname());
                            apiResp.getBody().getItems().add(item);
                        }
                    }
                } catch (LogicException e) {
                    apiResp.setMsg(e.getMessage());
                }
            } else {
                List<UserTransferMoneyWX> wxUserList = UserTransferMoneyWXService.self().findByUserId(loginUser.getId());
                if (wxUserList != null && wxUserList.size() > 0) {
                    apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                    apiResp.getBody().setItems(new ArrayList<>());
                    for (UserTransferMoneyWX wxUser : wxUserList) {
                        TransferMoneyWXUserListResponse.Item item = new TransferMoneyWXUserListResponse.Item();
                        item.setAppId(wxUser.getAppId());
                        item.setOpenId(wxUser.getOpenId());
                        item.setFaceImg(wxUser.getFaceImg());
                        item.setNickname(wxUser.getNickname());
                        apiResp.getBody().getItems().add(item);
                    }
                }
            }
        }
        return apiResp;
    }

    @Route(value = { "/agent/api/v1/transfer_money/qrcode/info.data" })
    public TransferMoneyQrcodeInfoResponse getTransferMoneyQrcode(HttpServletRequest request){
        TransferMoneyQrcodeInfoResponse apiResp = new TransferMoneyQrcodeInfoResponse(ClientAPICodeConstants.NULL_DATA, "暂无数据");
        LoginUser loginUser = WebUtils.getAttribute(request, WebConstants.ATTR_LOGIN_USER, LoginUser.class);
        UserTransferMoneyQrcode transferMoneyQrcode = UserTransferMoneyQrcodeService.self().getByUserId(loginUser.getId());
        if(transferMoneyQrcode != null){
            apiResp.setCode(ClientAPICodeConstants.SUCCESS,null);
            String resDomain = PropertyTools.get().getString("resDomain");
            apiResp.getBody().setQrcodeImg(WebUtils.setHttpDomain(resDomain,transferMoneyQrcode.getQrcode()));
            apiResp.getBody().setNote(transferMoneyQrcode.getNote());
        }
        return apiResp;
    }

    @Route(value = "/agent/api/v1/transfer_money/apply.do", method = "POST")
    public MyWalletTransferMoneyApplyResponse apply(HttpServletRequest request) {
        MyWalletTransferMoneyApplyResponse apiResp = new MyWalletTransferMoneyApplyResponse(ClientAPICodeConstants.EXECUTE_ERROR, "提现失败");
        MyWalletTransferMoneyApplyRequest apiReq = WebUtils.getJsonRequest(request, MyWalletTransferMoneyApplyRequest.class);
        LoginUser loginUser = WebUtils.getAttribute(request, WebConstants.ATTR_LOGIN_USER, LoginUser.class);
        if (loginUser != null && apiReq != null && apiReq.getBody().getType() != null && apiReq.getBody().getAccountGroupId() != null) {
            PayAccountGroup payAccountGroup = PayAccountGroupService.self().getById(apiReq.getBody().getAccountGroupId());
            if(payAccountGroup == null){
                apiResp.setMsg("未找到账号组，请联系客服人员");
                return apiResp;
            }
            if(!payAccountGroup.getCanTransfer() || StringTools.isBlank(payAccountGroup.getTransferConfig())){
                apiResp.setMsg("未开启用户提现功能");
                return apiResp;
            }

            CashWithdrawalConfig config = JsonTools.fromJson(payAccountGroup.getTransferConfig(), CashWithdrawalConfig.class);

            if(ReceivingMoneyType.Account.index().equals(apiReq.getBody().getType())) {
                if(!payAccountGroup.getWxTransfer()){
                    apiResp.setMsg("未开启微信号提现，请选择其他提现方式");
                    return apiResp;
                }
                if (StringTools.isBlank(payAccountGroup.getWxTransferAppId()) || !payAccountGroup.getWxTransferAppId().equals(apiReq.getBody().getAppId())) {
                    apiResp.setMsg("该应用不支持提现,请联系管理员");
                    return apiResp;
                }
            }

            // 检查提现时间
            boolean flag = false;
            String weekName = "";
            if (config.getMonthStartDay() != null && config.getMonthEndDay() != null) {
                int day = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
                if (day < config.getMonthStartDay() || day > config.getMonthEndDay()) {
                    apiResp.setMsg("请在每月" + config.getMonthStartDay() + "号-" + config.getMonthEndDay() + "号提现");
                    return apiResp;
                }
            }

            int week = DateTools.getWeek(new Date());
            if (StringUtils.isNotBlank(config.getCashWithdrawalWeeks())) {
                String[] names = config.getCashWithdrawalWeeks().split(",");
                for (String name : names) {
                    if (week == DefaultEnum.Weeks.valueOf(name).index()) {
                        if (StringUtils.isNotBlank(config.getCashWithdrawalTimes())) {
                            String[] times = config.getCashWithdrawalTimes().split(" - ");
                            if (times.length == 2) {
                                Date currentDate = new Date();
                                try {
                                    String dateStr = DateFormatUtils.format(currentDate, "yyyy-MM-dd");
                                    String startStr = dateStr + " " + times[0];
                                    Date startDate = DateUtils.parseDate(startStr, "yyyy-MM-dd HH:mm:ss");
                                    String endStr = dateStr + " " + times[1];
                                    Date endDate = DateUtils.parseDate(endStr, "yyyy-MM-dd HH:mm:ss");

                                    if (startDate.before(currentDate) && endDate.after(currentDate)) {
                                        flag = true;
                                    }
                                } catch (ParseException e) {
                                    log.error(e.getMessage(), e);
                                }
                            }
                        }
                    }
                    weekName = weekName + "," + DefaultEnum.Weeks.valueOf(name).note();
                }
                weekName = weekName.substring(1);
            }

            if (!flag) {
                apiResp.setMsg("请在" + weekName + "的" + config.getCashWithdrawalTimes() + "提现");
                return apiResp;
            }

            Integer transferMoney = NumberTools.changeMoney(apiReq.getBody().getMoney());
            UserWallet userWallet = UserWalletService.self().getByKeys(loginUser.getId(),payAccountGroup.getId());
            if(userWallet.getWithdrawalMoney() < transferMoney){
                apiResp.setMsg("金额不足");
                return apiResp;
            }
            String operateNote= "代理提现";
            User user = UserService.self().getById(loginUser.getId());
            WXTransferMoneyOrder transferMoneyOrder = null;
            UserTransferMoneyQrcode transferMoneyQrcode = null;
            if (ReceivingMoneyType.Account.index().equals(apiReq.getBody().getType())) {
                UserTransferMoneyWX wxUser = UserTransferMoneyWXService.self().getByKeys(payAccountGroup.getWxTransferAppId(),apiReq.getBody().getOpenId(),loginUser.getId());
                if (wxUser != null) {
                    if(StringTools.isBlank(wxUser.getNickname()) || StringTools.isBlank(wxUser.getFaceImg())){
                        apiResp.setMsg("请选择有昵称和头像的微信号提现");
                        return apiResp;
                    }
                    if(StringTools.isBlank(wxUser.getPhone())){
                        apiResp.setMsg("请选择绑定手机的微信号提现");
                        return apiResp;
                    }
                    transferMoneyOrder = new WXTransferMoneyOrder();
                    transferMoneyOrder.setAppType(wxUser.getAppType());
                    transferMoneyOrder.setAppId(wxUser.getAppId());
                    transferMoneyOrder.setOpenId(wxUser.getOpenId());
                    transferMoneyOrder.setNickname(wxUser.getNickname());
                    transferMoneyOrder.setFaceImg(wxUser.getFaceImg());
                    transferMoneyOrder.setName(wxUser.getName());
                    transferMoneyOrder.setPhone(wxUser.getPhone());

                    operateNote = operateNote + "(微信号)";
                }else{
                    apiResp.setMsg("未找到微信账号信息");
                    return apiResp;
                }
            }else if(ReceivingMoneyType.Qrcode.index().equals(apiReq.getBody().getType())){
                transferMoneyQrcode = UserTransferMoneyQrcodeService.self().getByUserId(user.getId());
                if(transferMoneyQrcode == null){
                    apiResp.setMsg("未找到用户的提现二维码");
                    return apiResp;
                }
                operateNote = operateNote + "(二维码)";
            }else{
                apiResp.setMsg("请选择有效的提现方式");
                return apiResp;
            }

            OperateInfo operateInfo = new OperateInfo(WebConstants.PROGRAM_TYPE,WebConstants.PROGRAM_TYPE_NAME);
            operateInfo.setOperator( EOperatorType.Agent.index(), loginUser.getNickname());
            operateInfo.setOperateNote(operateNote);

            UserTransferMoneyOrder applyEntity = new UserTransferMoneyOrder();
            applyEntity.setUserId(userWallet.getUserId());
            applyEntity.setAccountGroupId(userWallet.getAccountGroupId());
            applyEntity.setUserName(user.getName());
            applyEntity.setUserPhone(user.getPhone());
            applyEntity.setMoney(transferMoney);
            applyEntity.setProfitProportion(config.getServiceCharge());
            if (ReceivingMoneyType.Account.index().equals(apiReq.getBody().getType())) {
                applyEntity.setPayType(EPayType.WXPay.index());
                applyEntity.setReceivingType(apiReq.getBody().getType());

                try {
                    if (UserTransferMoneyOrderService.self().add(applyEntity,transferMoneyOrder,userWallet,operateInfo)) {
                        apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                        apiResp.getBody().setTradeNo(applyEntity.getTradeNo());
                    }
                } catch (LogicException e) {
                    apiResp.setMsg(e.getMessage());
                }
            }else if (ReceivingMoneyType.Qrcode.index().equals(apiReq.getBody().getType())) {
                //二维码提现
                if(UserTransferMoneyQrcodeEnum.Type.WXQrcode.index().equals(transferMoneyQrcode.getType())) {
                    applyEntity.setPayType(EPayType.WXPay.index());
                }else if(UserTransferMoneyQrcodeEnum.Type.AliQrcode.index().equals(transferMoneyQrcode.getType())){
                    applyEntity.setPayType(EPayType.Alipay.index());
                }
                applyEntity.setReceivingType(apiReq.getBody().getType());
                applyEntity.setReceivingQrcode(transferMoneyQrcode.getQrcode());

                try {
                    if (UserTransferMoneyOrderService.self().add(applyEntity,userWallet,operateInfo)) {
                        apiResp.setCode(ClientAPICodeConstants.SUCCESS, null);
                        apiResp.getBody().setTradeNo(applyEntity.getTradeNo());
                    }
                } catch (LogicException e) {
                    apiResp.setMsg(e.getMessage());
                }
            }
        }
        return apiResp;
    }
}
